﻿using System;
using System.ComponentModel.DataAnnotations;
using Legazpi.Payroll.DataAccess.Repositories;
using Legazpi.Payroll.DataAccess.DataObjects.Enums;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace Legazpi.Payroll.DataAccess.DataObjects
{
    public class DayTimeRecord : EntityBase<int>
    {
        private string logTimeRecords; 
        public string LogTimeRecords 
        {
            get { return logTimeRecords; }
            set
            {
                logTimeRecords = value;
                timeRecords = JsonConvert.DeserializeObject<List<TimeRecord>>(logTimeRecords);
            }
        }
        
        private double requiredWorkHours { get { return Employee.Detachment != null ? Employee.Detachment.WorkHours : 8 ; } }
       
        private List<TimeRecord> timeRecords;
        
        [NotMapped]
        public List<TimeRecord> TimeRecords
        {
            get
            {
                //var defaultDate = new DateTime(1900, 1, 1);
                foreach (var item in timeRecords)
                {
                    item.RequiredWorkHours = requiredWorkHours;
                    if (item.TimeIn.HasValue)
                    {
                        item.TimeIn = new DateTime(PayrollDate.Paydate.Year,
                            PayrollDate.Paydate.Month,
                            item.TimeIn.GetValueOrDefault().Day,
                            item.TimeIn.Value.Hour,
                            item.TimeIn.Value.Minute, 0);
                    }                    
                    if (item.TimeOut.HasValue)
                    {
                        item.TimeOut = new DateTime(PayrollDate.Paydate.Year,
                            PayrollDate.Paydate.Month,
                            item.TimeOut.Value.Day,
                            item.TimeOut.Value.Hour,
                            item.TimeOut.Value.Minute, 0);                    
                    }                    
                }
                
                return timeRecords;
            }
            private set
            {
                timeRecords = value;
            }
            
        }
        #region References
        [Column (Order = 1)]
        public int EmployeeId { get; set; }
        public virtual Employee Employee { get; set; }

        [Column (Order = 2)]
        public int PayrollDateId { get; set; }
        public virtual PayrollDate PayrollDate { get; set; }
        #endregion
        
        #region ComputedHours        
               
        [NotMapped]
        public double RegularTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.None).Sum(x => x.RegularHours);
            }
        }
        
        [NotMapped]
        public double LegalHolidayTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.Legal).Sum(x => x.RegularHours);
            }
        }

        [NotMapped]
        public double SpecialHolidayTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.Special).Sum(x => x.RegularHours);
            }
        }

        [NotMapped]
        public double RegularOverTimeHours 
        {
            get 
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.None).Sum(x => x.OverTime);
            }
        }

        [NotMapped]
        public double LegalOverTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.Legal).Sum(x => x.OverTime);
            }
        }

        [NotMapped]
        public double SpecialOverTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.Special).Sum(x => x.OverTime);
            }
        }

        [NotMapped]
        public double RegularNightDiffTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.None).Sum(x => x.NightDifference);
            }
        }

        [NotMapped]
        public double LegalNightDiffTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.Legal).Sum(x => x.NightDifference);
            }
        }

        [NotMapped]
        public double SpecialNightDiffTimeHours
        {
            get
            {
                return TimeRecords.Where(x => x.Holiday == (int)HolidayType.Special).Sum(x => x.NightDifference);
            }
        }

        [NotMapped]
        public double TotalNightDifferential
        {
            get
            {
                return RegularNightDiffTimeHours + LegalNightDiffTimeHours + SpecialNightDiffTimeHours;
            }
        }

        [NotMapped]
        public double TotalOverTime
        {
            get
            {
                return RegularOverTimeHours + LegalOverTimeHours+ SpecialOverTimeHours;
            }
        }

        #endregion
        
        public DayTimeRecord()
        {
            timeRecords = new List<TimeRecord>();
        }
    }
}
